﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpGraphicsNodeInterface.h"
#include "ElementId.h"
#include "GraphicsNodeId.h"
#include "WeakPtr.h"
#include "OwnerPtr.h"
#include "Matrix4d.h"
#include "GraphicsNodeAndTransform.h"
#include "GraphicsNodeReferenceType.h"
#include <vector>
#include "ContainerUtil.h"


namespace gcmp
{
    class ICurve3d;

    /// \brief 表示对一个图形节点的引用
    class GCMP_GRAPHICS_NODE_INTERFACE_EXPORT IGraphicsNodeReference : public IDbObject
    {
        CANNOT_ASSIGN(IGraphicsNodeReference);

        DEFINE_CAST_DERIVED(IGraphicsNodeReference, IDbObject)

    public:
        /// \brief 析构器
        virtual ~IGraphicsNodeReference();
        

    public:
        /// \brief 克隆
        /// \return 克隆的对象
        virtual OwnerPtr<IGraphicsNodeReference> Clone() const = 0;

        /// \brief 获取所属的Element
        /// \return Element的id
        virtual ElementId GetElementId() const = 0;

        /// \brief 获取节点引用类型
        /// \return 节点引用类型，参见：GraphicsNodeReferenceType
        /// \see GraphicsNodeReferenceType
        virtual GraphicsNodeReferenceType GetGraphicsNodeReferenceType() const = 0;

        /// \brief 设置节点引用类型
        /// \param referenceType 节点引用类型，参见：GraphicsNodeReferenceType
        /// \return true-设置成功；false-设置失败
        /// \see GraphicsNodeReferenceType
        virtual bool SetGraphicsNodeReferenceType(GraphicsNodeReferenceType referenceType) = 0;

        /// \brief 获取相交的原始图形节点
        /// \return 相交的原始图形节点
        virtual const IGraphicsNode* GetUntransformedIntersectGraphicsNode() const = 0;

        /// \brief 获取相交的图形节点及其变换矩阵
        /// \return 相交的图形节点及其变换矩阵
        virtual OwnerPtr<GraphicsNodeAndTransform> GetIntersectGraphicsNode() const = 0;

        /// \brief 获取原始交点坐标
        /// \return 原始交点坐标
        virtual const Vector3d& GetUntransformedIntersectPoint() const = 0;

        /// \brief 获取变换后的交点坐标
        /// \return 变换后的交点坐标
        virtual Vector3d GetTransformedIntersectPoint() const = 0;

        /// \brief 获取相交数据中原始的三角面片，该接口主要针对MeshBody，相交数据中的三角面片采用三个顶点坐标表示
        /// \return 原始的三角面片
        virtual const std::vector<Vector3d>& GetUntransformedIntersectTriangle() const = 0;

        /// \brief 获取相交数据中变换后的三角面片，该接口主要针对MeshBody，相交数据中的三角面片采用三个顶点坐标表示
        /// \return 变换后的三角面片
        virtual const std::vector<Vector3d> GetTransformedIntersectTriangle() const = 0;

        /// \brief 获取原始相交的曲线段
        /// \return 原始相交的曲线段
        virtual const ICurve3d* GetUntransformedIntersectCurve3d() const = 0;

        /// \brief 获取交点状态
        /// \return -2/-1/0/1/2
        virtual int IsRealIntersect() const = 0;
    
        /// \brief 获取是否是整个Element图形表达的引用
        /// \return true-是；false-否
        virtual bool IsGraphicsElementShapeReference() const = 0;

        /// \brief 获取是否是合法引用
        /// \return true-是；false-否
        virtual bool IsValid() const = 0;

        /// \brief 设置所引用的Element
        /// \param id 所引用的Element的id
        /// \return 无
        virtual void SetElementId(const ElementId& id) = 0;

        /// \brief 获取叶子节点id标识符
        /// \return 叶子节点id标识符
        virtual GraphicsNodeId GetGraphicsNodeId() const = 0;

        /// \brief 设置叶子节点id标识符
        /// \param graphicsNodeId 叶子节点id标识符
        /// \return 无
        virtual void SetGraphicsNodeId(const GraphicsNodeId& graphicsNodeId) = 0;

        /// \brief 获取节点id路径
        /// \return 节点id路径
        virtual const std::vector<GraphicsNodeId>& GetGraphicsNodeIdPath() const = 0;

        /// \brief 设置节点id路径
        /// \param graphicsNodeIdPath 节点id路径
        /// \return 节点id路径
        virtual void SetGraphicsNodeIdPath(const std::vector<GraphicsNodeId>& graphicsNodeIdPath) = 0;

        /// \brief 获取节点描述信息(用于消息提示)
        /// \return 节点描述信息
        virtual std::wstring GetDescriptionString() const = 0;

        /// \brief 判断引用是否是指向同一个图形节点
        ///
        /// 此函数不关心引用者添加的额外几何引用标识
        /// \param graphicsNodeReference 图形节点引用对象
        /// \return true-是；false-否
        virtual bool IsSameGraphicsNode(const IGraphicsNodeReference& graphicsNodeReference) const = 0;

        /// \brief 设置相交数据
        /// \param orignalPoint 原始交点坐标
        /// \param pOriginalGraphicsNode 原始图形节点        
        /// \param pTransform 变换矩阵
        /// \param iRealIntersect 实交/虚交/待定
        /// \param intersectionTriangle 与MeshBody求交得到的三角面片
        /// \return 无
        virtual void SetIntersectData(const Vector3d& orignalPoint, const IGraphicsNode* pOriginalGraphicsNode = nullptr, const Matrix4d* pTransform = nullptr, int iRealIntersect = 0, const std::vector<Vector3d>& intersectionTriangle = std::vector<Vector3d>(), OwnerPtr<ICurve3d> opCurve3d = nullptr) = 0;

        /// \brief 设置矩形相交数据
        /// \param pOriginalGraphicsNode 原始图形节点
        /// \param pTransform 变换矩阵
        /// \return 无
        virtual void SetRectIntersectData(const IGraphicsNode* pOriginalGraphicsNode, const Matrix4d* pTransform = nullptr) = 0;

        /// \brief 获取节点路径
        /// \return 节点路径
        virtual const std::vector<const IGraphicsNode*>& GetGraphicsNodePtrPath() const = 0;

        /// \brief 将目标对象赋值给自己
        /// \param other 目标对象
        /// \return 无
        virtual void Set(const IGraphicsNodeReference& other) = 0;

        /// \brief 与目标对象做相等比较
        /// \param other 目标对象
        /// \return true-相等；false-不相等
        virtual bool EqualTo(const IGraphicsNodeReference& other) const = 0;

        /// \brief 与目标对象做小于比较
        /// \param other 目标对象
        /// \return true-小于；false-不小于
        virtual bool LessThan(const IGraphicsNodeReference& other) const = 0;

    public:
        /// \brief 创建默认的图形节点的引用对象
        /// \return 图形节点的引用对象
        static OwnerPtr<IGraphicsNodeReference> Create();

        /// \brief 复制构造一个图形节点的引用对象
        /// \param source 复制源对象
        /// \return 图形节点的引用对象
        static OwnerPtr<IGraphicsNodeReference> Create(const IGraphicsNodeReference& source);

        /// \brief 构造一个图形节点的引用对象
        /// \param elementId 被引用的Element的id
        /// \param graphicsNodeId 图形节点的id标识
        /// \param referenceType 节点引用类型，参见：GraphicsNodeReferenceType
        /// \return 图形节点的引用对象
        /// \see GraphicsNodeReferenceType
        static OwnerPtr<IGraphicsNodeReference> Create(const ElementId& elementId, GraphicsNodeId graphicsNodeId, GraphicsNodeReferenceType referenceType = GraphicsNodeReferenceType::GraphicsNodeSelf);
 
        /// \brief 构造一个图形节点的引用对象
        /// \param elementId 被引用的Element的id
        /// \param graphicsNodeIdPath 图形节点的id路径
        /// \param referenceType 节点引用类型，参见：GraphicsNodeReferenceType
        /// \return 图形节点的引用对象
        /// \see GraphicsNodeReferenceType
        static OwnerPtr<IGraphicsNodeReference> Create(const ElementId& elementId, const std::vector<GraphicsNodeId>& graphicsNodeIdPath, GraphicsNodeReferenceType referenceType = GraphicsNodeReferenceType::GraphicsNodeSelf);

        /// \brief 构造一个图形节点的引用对象
        /// \param elementId 被引用的Element的id
        /// \param graphicsNodeIdPath 图形节点的id路径
        /// \param graphicsNodePtrPath 图形节点的指针路径
        /// \param referenceType 节点引用类型，参见：GraphicsNodeReferenceType
        /// \return 图形节点的引用对象
        /// \see GraphicsNodeReferenceType
        static OwnerPtr<IGraphicsNodeReference> Create(const ElementId& elementId, const std::vector<GraphicsNodeId>& graphicsNodeIdPath, const std::vector<const IGraphicsNode*>& graphicsNodePtrPath, GraphicsNodeReferenceType referenceType = GraphicsNodeReferenceType::GraphicsNodeSelf);

        /// \brief 构造一个图形节点的引用对象
        /// \param elementId 被引用的Element的id
        /// \return 图形节点的引用对象
        static OwnerPtr<IGraphicsNodeReference> CreateGraphicsElementShapeReference(const ElementId& elementId);
    };
}

